#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h> 
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Protocol/LoadedImage.h>

EFI_STATUS
EFIAPI
UefiMain (
  IN EFI_HANDLE        MyImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                         Status;
  UINTN                              Index;
  UINTN                              NoHandles;
  EFI_HANDLE                       * Buffer;
  EFI_DEVICE_PATH_PROTOCOL         * DevicePath;
  EFI_HANDLE                         ImageHandle;
  // CHAR16                           * EfiImageName = L"\\EFI\\BOOT\\BOOTX64.efi";
  CHAR16                           * EfiImageName = L"\\HelloWorld.efi";

  Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &NoHandles, &Buffer);
  if (EFI_ERROR(Status)) {
    Print(L"Unsupported\n\r");
    return 0;
  }

  for (Index = 0; Index < NoHandles; Index ++){
    DevicePath  = FileDevicePath (Buffer[Index], EfiImageName);
    Status = gBS->LoadImage (
                    FALSE,
                    gImageHandle,
                    DevicePath,
                    NULL,
                    0,
                    &ImageHandle
                    );
    if (EFI_ERROR (Status)) {
      Print(L"Load Image error %r %x\n\r", Status, gImageHandle);
      continue;
    }

    Status = gBS->StartImage (ImageHandle, NULL, NULL);
    if (Status == EFI_SUCCESS) {
      Print (L"Program run successfully!\n\r", Status);
    }
    else if (Status == EFI_INVALID_PARAMETER) {
      Print (L"Program can not start!\n\r");
    }
    else if (Status == EFI_SECURITY_VIOLATION) {
      Print (L"Program can not start!\n\r");
    }
    else {
      Print(L"Program exit with an error status: %r\n\r", Status);
      break;
    }
  }

  return Status;
}